% @author : slandarer
A = [2 -1; -1 4];
b = [0; 2];
x = [-5; -5];

% 构造等价函数
vx  = sym('x',size(b));
phi = vx.'*A*vx./2-b.'*vx;
phi = matlabFunction(phi);

% 坐标区域基础修饰
ax = gca; view(-71,38); grid on
ax.NextPlot      = 'add';
ax.Projection    = 'perspective';
ax.LineWidth     =  .8;
ax.XMinorTick    = 'on';
ax.YMinorTick    = 'on';
ax.ZMinorTick    = 'on';
ax.TickLength    = [.02,.01];
ax.GridLineStyle = ':';
ax.FontName      = 'Cambria';

% 基本绘图
[X1,X2] = meshgrid(linspace(-5,5,50));
surf(X1,X2,phi(X1,X2),'EdgeColor','none');
contour(X1,X2,phi(X1,X2),20,'LineWidth',1)

% 创建gif图
DelayTime = .5;
F = getframe(ax);
[imind,cm] = rgb2ind(F.cdata,256);
imwrite(imind,cm,'test.gif','gif','Loopcount',inf,'DelayTime',DelayTime);

epn    = inf;     % 初始精度
tol    = 1e-6;    % 要求精度
maxItr = 1e3;     % 最大轮数

k = 1;
while k<=maxItr && epn>tol
    p = b-A*x;                % 求解梯度反方向
    a = dot(p,p)./dot(A*p,p); % 求解\alpha值
    x = x+a.*p;               % 更新变量x值

    xx = [x-a.*p, x];
    yy = [phi(xx(1,1),xx(2,1)); phi(xx(1,2),xx(2,2))];
    % 绘制搜索过程
    plot3(xx(1,:),xx(2,:),yy.','LineWidth',1,'LineStyle','--',...
        'Color','r','Marker','o','MarkerFaceColor','r','MarkerSize',3)
    plot3(xx(1,:),xx(2,:),[0,0],'LineWidth',1,'LineStyle','--',...
        'Color','r','Marker','o','MarkerFaceColor','r','MarkerSize',3)
    % 制作gif时至展示前几帧
    if k<6
        pause(.5);
        F = getframe(ax);
        [imind,cm] = rgb2ind(F.cdata,256);
        imwrite(imind,cm,'test.gif','gif','WriteMode','append','DelayTime',DelayTime);
    end
    
    k = k+1;
    epn = norm(a.*p);
end
